<?php

namespace App;

use App\Events\ThreadHasNewReply;
use App\Events\ThreadReceivedNewReply;
use App\Notifications\ThreadWasUpdated;
use App\traits\RecordsActivity;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Redis;

class Thread extends Model
{
    //

    use RecordsActivity;

    protected $guarded = []; //可以更新任何属性，后期要修复此漏洞
    protected $with = ['creator','channel'];
    protected $appends = ['isSubscribedTo'];

    protected static function boot()
    {
        parent::boot(); // TODO: Change the autogenerated stub

        /*static::addGlobalScope('replycount',function ($builder){
            $builder->withCount('replies');
        });*/

        static::deleting(function ($thread){
            $thread->replies->each->delete();
        });


    }



    public function path()
    {
        return "/threads/{$this->channel->slug}/{$this->id}";
    }

    /*public function replies()
    {
        return $this->hasMany(Reply::class);
    }*/

    public function replies()
    {
        /*return $this->hasMany(Reply::class)
            ->withCount('favorites')
            ->with('owner');*/
        /*因为在Reply.php里已经定义了
        protected $with = ['owner', 'favorites'];
        以及Favoritable.php当中定义了

        public function getFavoritesCountAttribute()
        {
            return $this->favorites->count();
        }
        所以在Thread.php当中对关联关系replies进行修改*/

        return $this->hasMany(Reply::class);
    }

    public function creator()
    {
        return $this->belongsTo(User::class,'user_id');
    }

    public function addReply($reply)
    {
        /*return $this->replies()->create($reply);*/

        $reply = $this->replies()->create($reply);
        event(new ThreadReceivedNewReply($reply));

//        $this->notifySubscribers($reply);

        return $reply;

        // Prepare notifications for all subscribers
        /*foreach ($this->subscriptions as $subscription) {
            if($subscription->user_id != $reply->user_id){
                $subscription->user->notify(new ThreadWasUpdated($this,$reply));
            }
        }*/


      /*  $this->subscriptions
            ->filter (function ($sub) use ($reply){
                return $sub->user_id != $reply->user_id;
            })->each->notify($reply);*/




        /*$this->subscriptions
            ->filter (function ($sub) use ($reply){
                return $sub->user_id != $reply->user_id;
            })
            ->each (function ($sub) use ($reply){
                $sub->user->notify(new ThreadWasUpdated($this,$reply));
            });*/


        /*$this->subscriptions
            ->where('user_id','!=',$reply->user_id)
            ->each (function ($sub) use ($reply){
                $sub->user->notify(new ThreadWasUpdated($this,$reply));
            });*/



    }


    public function notifySubscribers($reply)
    {
        $this->subscriptions
            ->where('user_id','!=',$reply->user_id)
            ->each (function ($sub) use ($reply){
                $sub->user->notify(new ThreadWasUpdated($this,$reply));
            });


        /*$this->subscriptions()->get()
            ->where('user_id','!=',$reply->user_id)
            ->each->notify($reply);*/
    }

    public function channel()
    {
        return $this->belongsTo(Channel::class);
    }

    public function scopeFilter($query,$filters)
    {
        return $filters->apply($query);
    }

    public function subscribe($userId = null)
    {
        $this->subscriptions()->create([
            'user_id' => $userId ?: auth()->id()
        ]);

        return $this;
    }

    public function unsubscribe($userId = null)
    {
        $this->subscriptions()
            ->where('user_id',$userId ?: auth()->id())
            ->delete();

    }

    public function subscriptions(){

        return $this->hasMany(ThreadSubscription::class);
    }

    public function getIsSubscribedToAttribute()
    {
        return $this->subscriptions()
            ->where('user_id',auth()->id())
            ->exists();
    }

    public function hasUpdatesFor($user)
    {
        // Look in the cache for the proper key
        // compare that carbon instance with the $thread->updated_at

        $key = $user->visitedThreadCacheKey($this);

        return $this->updated_at > cache($key);
    }

    public function visits()
    {
        return new Visits($this);
    }


}
